import {Injectable} from "@angular/core";
import {Constants} from "@app/shared/constant";
import {HttpClient, HttpErrorResponse, HttpHandler} from "@angular/common/http";
import {catchError, Observable, OperatorFunction, tap, throwError} from "rxjs";
import HttpUtil from "@core/http/HttpUtil";

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  constructor(private httpClient: HttpClient) {
  }

  public static get token(): string | null {
    return localStorage.getItem(Constants.jwtToken);
  }

  public static get refreshToken(): string | null {
    return localStorage.getItem(Constants.jwtRefreshToken);
  }

  public saveToken(res: LoginResponse) {
    if (res.token !== null) {
      localStorage.setItem(Constants.jwtToken, res.token);
    }
    if (res.refreshToken !== null)
      localStorage.setItem(Constants.jwtRefreshToken, res.refreshToken);
  }

  public clearToken() {
    localStorage.removeItem(Constants.jwtToken);
    localStorage.removeItem(Constants.jwtRefreshToken);
  }

  public login(loginData: LoginData): Observable<LoginResponse> {
    return this.httpClient.post('/api/auth/login', loginData,
      HttpUtil.defaultHttpOption()).pipe(
      tap((res: LoginResponse): void => {
        if (res !== null && res.token)
          this.saveToken(res);
        else
          throwError(() => res)
      }) as OperatorFunction<Object, LoginResponse>,
      catchError((error: HttpErrorResponse): Observable<never> => {
        return throwError(() => error)
      })
    )
  }

  public register(loginData: LoginData): Observable<boolean> {
    return this.httpClient.post('/api/auth/register', loginData,
      HttpUtil.defaultHttpOption()).pipe(
      tap(function (value: boolean) {
        return true
      }) as OperatorFunction<Object, boolean>,
      catchError((error: HttpErrorResponse): Observable<never> => {
        return throwError(() => error)
      })
    )
  }

  public postRefreshToken(refreshToken: string): Observable<LoginResponse> {
    return this.httpClient.post('/api/auth/token', refreshToken,
      HttpUtil.defaultHttpOption()).pipe(
      tap((res: LoginResponse): void => {
        this.saveToken(res);
      }) as OperatorFunction<Object, LoginResponse>,
      catchError((error: HttpErrorResponse): Observable<never> => {
        return throwError(() => error)
      })
    )
  }
}
